<?php
	/**
	 * User: yxt
	 * Date: 2016/3/29
	 * Time: 8:58
	 */

include_once dirname(__FILE__).'/np_db_mysql.class.php';
include_once dirname(__FILE__).'/np_db_mysqli.class.php';
include_once dirname(__FILE__).'/np_kv_cache_redis.class.php';
	if(defined('mysql_driver_type')&&strtolower(mysql_driver_type)==='mysqli')
	{
		class np_db_mysql_with_cache_parent extends np_db_mysqli_class
		{

		}
	}
	else
	{
		class np_db_mysql_with_cache_parent extends np_db_mysql_class
		{
		}
	}
	class np_db_mysql_with_cache extends np_db_mysql_with_cache_parent
	{
		private $db_query_cache_enabled=0;//db查询缓存是否开启，0关闭，1开启
		private $arr_cache_params=array();//db缓存参数配置，各种缓存因子，缓存时长之类的配置
		public $str_cache_key='';//缓存key
		private $obj_kv_cache_redis=null;
		private $str_sql='';
		static $int_sql_all=0;
		static $int_cache_sql=0;

		private $opened = false;

		public function __construct ($config)
		{
			parent::__construct($config);
			if(defined('g_debug')&&g_debug==1)
			{
				foreach($config['db_cache_params_config'] as $key=>$val)
				{
					header("ng_db_query_cache_params_{$key}:{$val}");
				}
			}
			$this->arr_cache_params=$config['db_cache_params_config'];
			$arr_kv_cache_config=np_kv_cache_build_config(NP_KV_CACHE_TYPE_REDIS,1,$config['db_cache_config']);
			$this->obj_kv_cache_redis=np_kv_cache_factory_create($arr_kv_cache_config);
//            开启数据压缩
            $this->obj_kv_cache_redis->kv_zip_enable(true);
			$this->db_query_cache_enabled=$config['db_cache_params_config']['ng_cache_enable'];
		}

		public function enable_cache()
		{
			$this->db_query_cache_enabled=1;
		}

		public function disable_cache()
		{
			$this->db_query_cache_enabled=0;
		}

		/**
		 * 2016年3月29日17:35:25
		 * 于小涛
		 * 创建缓存key
		 * @param $str_sql sql语句
		 *
		 * @return string
		 */
		private function __create_cache_key($str_sql)
		{
			$ng_api_cache_key=$this->arr_cache_params['ng_api_cache_key'];
			$ng_db_cache_key=$this->arr_cache_params['ng_db_cache_key'];
			$func=$this->arr_cache_params['func'];
			$this->str_cache_key=md5($ng_api_cache_key.$ng_db_cache_key.$func.$str_sql);
			return $this->str_cache_key;
		}

		/**
		 * 2016年3月29日17:35:50
		 * 设置缓存
		 * @param $str_sql sql语句
		 * @param $mixed_val 结果
		 *
		 * @return bool
		 */
		private function set_cache($str_sql,$mixed_val)
		{
			$bool_re=false;
			//如果缓存开启
			if($this->db_query_cache_enabled)
			{
				$str_key=$this->__create_cache_key($str_sql);
				$bool_re = $this->obj_kv_cache_redis->set($str_key,$mixed_val,$this->arr_cache_params['ng_cache_time']);
			}
			return $bool_re;
		}

		/**
		 * 2016年3月29日17:35:50
		 * 获取缓存
		 * @param $str_sql sql语句
		 *
		 * @return bool
		 */
		private function get_cache($str_sql)
		{
			$bool_re=false;
			if($this->db_query_cache_enabled)
			{
				$str_key=$this->__create_cache_key($str_sql);
				$bool_re =  $this->obj_kv_cache_redis->get($str_key);
				}
			return $bool_re;
		}

		public function query ($sql)
		{
			$this->str_sql=$sql;

			

			return true;
		}

		public function open()
		{
			return true;
		}

		public function close() {
			if ($this->opened===true)
			{
				parent::close();
			}
			$this->obj_kv_cache_redis->close();
			return TRUE;
		}

		public function execute($sql)
		{
			if ($this->opened === false)
			{
				$this->opened = parent::open();
			}
			
			if ($this->opened === false)
			{
				return false;
			}
			return parent::execute($sql);
		}

		public function get_query_result($is_free_after_get = TRUE)
		{
			self::$int_sql_all++;
			//如果不是强刷新，并且开启了缓存开关
			if(!$this->arr_cache_params['flush_db_cache'])
			{
				$mixed_data=$this->get_cache($this->str_sql);
				if($mixed_data !== false)
				{
					self::$int_cache_sql++;
					if(defined('g_debug')&&g_debug==1)
					{
						header("db_query_cache_sql_cache_hit:sql[{$this->str_sql}]");
					}
					return $mixed_data;
				}
			}
			if ($this->opened === false)
			{
				$this->opened = parent::open();
			}
			
			if ($this->opened === false)
			{
				return false;
			}
			$mixed_query_data = parent::query($this->str_sql);
			//是强刷新或者获取缓存失败，则从数据库读
			$mixed_query_data=parent::get_query_result($is_free_after_get);
			if($mixed_query_data!==false)
			{
				$bool_re=$this->set_cache($this->str_sql,$mixed_query_data);
				if(defined('g_debug')&&g_debug==1)
				{
					if($bool_re)
					{
						header("db_query_cache_set_success:sql[{$this->str_sql}]");
					}
					else
					{
						header("db_query_cache_set_fail:[{$this->str_sql}]");
					}
				}
			}
			return $mixed_query_data;
		}
		public function __destruct ()
		{
			$this->close();
		}
	}